package srv

import (
	"context"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/asserts"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/beans"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/ferror"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/sqls"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/xids"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/dao"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/gqlgen/mgr/gmodel"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/model"
	"gitee.com/shiqiyue/xd-bi/pkg/gorms"
	"github.com/dgryski/trifles/uuid"
	"go.uber.org/zap/buffer"
	"gorm.io/gorm"
	"text/template"
)

func SqlReportinit() {
	sqlReportSrv := &SqlReportSrv{}
	err := beans.ProvideBean(sqlReportSrv)
	asserts.Nil(err, err)
}

type SqlReportSrv struct {
	BaseSrv
	*dao.SqlReportDao     `inject:""`
	Db                    *gorm.DB               `inject:""`
	ReportResultColumnSrv *ReportResultColumnSrv `inject:""`
	ReportFormSrv         *ReportFormSrv         `inject:""`
}

// 通过reportId获取
func (s *SqlReportSrv) GetByReportId(ctx context.Context, db *gorm.DB, reportId string) (*model.SqlReport, error) {
	var result = &model.SqlReport{}
	err := db.Model(&model.SqlReport{}).Where("report_id = ?", reportId).Take(result).Error
	if err == gorm.ErrRecordNotFound {
		return nil, nil
	}
	return result, err
}

// 更新或者插入
func (s *SqlReportSrv) Update(ctx context.Context, db *gorm.DB, req gmodel.UpdateReportSQL) (err error) {
	tx := db.Begin()
	defer func() {
		if d := recover(); d != nil {
			tx.Rollback()
			panic(d)
			return
		}
		if err != nil {
			tx.Rollback()
			return
		}
		tx.Commit()
	}()

	if req.ValidateAndGenerateReturns {
		// 解析sql
		sql := req.SQL
		params := map[string]interface{}{}
		if err != nil {
			return ferror.Wrap("填充go template参数失败", err)
		}
		// form参数
		forms, err := s.ReportFormSrv.GetByReportId(ctx, tx, req.ReportID)
		if err != nil {
			return ferror.Wrap("获取form参数失败", err)

		}
		for _, form := range forms {
			params[form.AttributeName] = s.ReportFormSrv.FormDefaultValue(form)
		}
		err = sqls.FillTestAuthMap(ctx, params)
		if err != nil {
			return ferror.Wrap("填充权限信息异常", err)
		}
		// 填充用户信息
		err = sqls.FillUserMap(ctx, params)
		if err != nil {
			return ferror.Wrap("填充用户信息异常", err)
		}
		// 分页参数
		params["limit"] = 10
		params["offset"] = 10
		if req.SupportGoTemplate {
			sql = gorms.CleanSql(sql)
			t, err := template.New(uuid.UUIDv4()).Parse(sql)
			if err != nil {
				return ferror.Wrap("执行go template失败", err)
			}
			bs := buffer.Buffer{}
			err = t.Execute(&bs, params)
			if err != nil {
				return ferror.Wrap("执行go template失败", err)
			}
			sql = bs.String()
		}
		d := db.Raw(sql, params)
		sql = gorms.GetSql(d)
		columns, err := sqls.ParseSelectColumns(sql)
		if err != nil {
			return ferror.Wrap("解析sql失败,sql:"+sql, err)
		}
		// 处理表单返回参数
		for i := range columns {
			columnName := columns[i]
			resultColumn, err := s.ReportResultColumnSrv.GetByReportIdAndAttributeName(ctx, tx, req.ReportID, columnName)
			if err != nil {
				return err
			}
			if resultColumn == nil {
				err := s.ReportResultColumnSrv.InsertResultColumn(ctx, tx, req.ReportID, columnName)
				if err != nil {
					return err
				}
			}
		}
	}

	// 处理sql report
	sqlReport, err := s.GetByReportId(ctx, tx, req.ReportID)
	if err != nil {
		return err
	}
	if sqlReport == nil {
		report := &model.SqlReport{
			SqlReportId:       xids.GetXid(ctx),
			ReportId:          req.ReportID,
			Sql:               req.SQL,
			DbId:              req.DbID,
			SupportGoTemplate: req.SupportGoTemplate,
		}
		if req.CountSQL != nil {
			report.CountSql = *req.CountSQL
		}
		err = s.Insert(ctx, tx, report)
		if err != nil {
			return err
		}
	} else {
		updateParam := map[string]interface{}{}
		updateParam["sql"] = req.SQL
		updateParam["db_id"] = req.DbID
		updateParam["support_go_template"] = req.SupportGoTemplate
		updateParam["count_sql"] = req.CountSQL
		err = s.UpdateById(ctx, tx, sqlReport.ID, updateParam)
		if err != nil {
			return err
		}
	}

	return nil
}
